﻿using FlyingCircusWebIS.Models;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.OleDb;
using System.Linq;
using System.Web;

namespace FlyingCircusWebIS.Models
{
    public class PessoaDAO: IPessoaDAO
    {
        private IEnderecoDAO enderecoDAO;
        private ITelefoneDAO telefoneDAO;

        public PessoaDAO()
        {
            enderecoDAO = new EnderecoDAO();
            telefoneDAO = new TelefoneDAO();
        }

        public void Adicionar(Pessoa entidade, DbTransaction transacao = null)
        {
            string sqlAtualizar
                = "insert into Pessoa (IdPessoa, NivelPessoa, UsuarioSistema, SenhaSistema, NomeCompleto, " + 
                "Sexo, CPF, DataNascimento, Email, IdEndereco, Ocupacao, Renda, DescontoEspecial, PorcDescontoEspecial, RecebeInfoMarketing, CadastroAtivo) " + 
                "values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlAtualizar;
            if (transacao != null)
                comando.Transaction = transacao as OleDbTransaction;

            OleDbParameter pIdPessoa = new OleDbParameter("IdPessoa", OleDbType.Integer);
            pIdPessoa.Value = entidade.IdPessoa;
            comando.Parameters.Add(pIdPessoa);

            OleDbParameter pNivel = new OleDbParameter("NivelPessoa", OleDbType.VarChar);
            string nivelPessoa = entidade.NivelPessoa;
            if (string.IsNullOrEmpty(nivelPessoa))
                pNivel.Value = "C";
            else
                pNivel.Value = nivelPessoa;
            comando.Parameters.Add(pNivel);

            OleDbParameter pUsuarioSistema = new OleDbParameter("UsuarioSistema", OleDbType.VarChar);
            pUsuarioSistema.Value = entidade.UsuarioSistema;
            comando.Parameters.Add(pUsuarioSistema);

            OleDbParameter pSenhaSistema = new OleDbParameter("SenhaSistema", OleDbType.VarChar);
            pSenhaSistema.Value = entidade.SenhaSistema;
            comando.Parameters.Add(pSenhaSistema);

            OleDbParameter pNomeCompleto = new OleDbParameter("NomeCompleto", OleDbType.VarChar);
            pNomeCompleto.Value = entidade.NomeCompleto;
            comando.Parameters.Add(pNomeCompleto);

            OleDbParameter pSexo = new OleDbParameter("Sexo", OleDbType.VarChar);
            pSexo.Value = entidade.Sexo ;
            comando.Parameters.Add(pSexo);

            OleDbParameter pCPF = new OleDbParameter("CPF", OleDbType.VarChar);
            pCPF.Value = entidade.CPF;
            comando.Parameters.Add(pCPF);

            OleDbParameter pNascimento = new OleDbParameter("DataNascimento", OleDbType.Date);
            pNascimento.Value = entidade.DataNascimento;
            comando.Parameters.Add(pNascimento);

            OleDbParameter pEmail = new OleDbParameter("Email", OleDbType.VarChar);
            pEmail.Value = entidade.Email;
            comando.Parameters.Add(pEmail);

            OleDbParameter pIdEndereco = new OleDbParameter("IdEndereco", OleDbType.VarChar);
            pIdEndereco.Value = entidade.IdEndereco;
            comando.Parameters.Add(pIdEndereco);

            OleDbParameter pOcupacao = new OleDbParameter("Ocupacao", OleDbType.VarChar);
            string ocupacao = entidade.Ocupacao;
            if (string.IsNullOrEmpty(ocupacao))
                pOcupacao.Value = DBNull.Value;
            else
                pOcupacao.Value = ocupacao;
            comando.Parameters.Add(pOcupacao);

            OleDbParameter pRenda = new OleDbParameter("Renda", OleDbType.Numeric);
            Decimal? renda = entidade.Renda;
            if (renda == null || renda == 0)
                pRenda.Value = DBNull.Value;
            else
                pRenda.Value = renda;
            comando.Parameters.Add(pRenda);

            OleDbParameter pDescontoEspecial = new OleDbParameter("DescontoEspecial", OleDbType.VarChar);
            if (string.IsNullOrEmpty(entidade.DescontoEspecial))
                pDescontoEspecial.Value = "N";
            else
                pDescontoEspecial.Value = entidade.DescontoEspecial;
            comando.Parameters.Add(pDescontoEspecial);

            OleDbParameter pPorcDescontoEspecial = new OleDbParameter("PorcDescontoEspecial", OleDbType.Numeric);
            Decimal? porcDescontoEspecial = entidade.PorcDescontoEspecial;
            if (porcDescontoEspecial == null || porcDescontoEspecial == Decimal.Zero)
                pPorcDescontoEspecial.Value = 0.0;
            else
                pPorcDescontoEspecial.Value = porcDescontoEspecial;
            comando.Parameters.Add(pPorcDescontoEspecial);


            OleDbParameter pRecebeInfoMarketing = new OleDbParameter("RecebeInfoMarketing", OleDbType.VarChar);
            string recebeMarketing = entidade.RecebeInfoMarketing;
            if (string.IsNullOrEmpty(recebeMarketing))
                pRecebeInfoMarketing.Value = "S";
            else
                pRecebeInfoMarketing.Value = recebeMarketing;
            comando.Parameters.Add(pRecebeInfoMarketing);

            OleDbParameter pCadastroAtivo = new OleDbParameter("CadastroAtivo", OleDbType.VarChar);
            string cadastroAtivo = entidade.CadastroAtivo;
            if (string.IsNullOrEmpty(cadastroAtivo))
                pCadastroAtivo.Value = "N";
            else
                pCadastroAtivo.Value = cadastroAtivo;
            comando.Parameters.Add(pCadastroAtivo);


            // Insert
            comando.ExecuteNonQuery();
            comando.Dispose();
        }

        public void Atualizar(Pessoa entidade, DbTransaction transacao = null)
        {
            string sqlAtualizar
               = "update Pessoa set NivelPessoa = ?, UsuarioSistema = ?, SenhaSistema = ?, NomeCompleto = ?, " +
               "Sexo = ?, CPF = ?, DataNascimento = ?, Email = ?, IdEndereco = ?, Ocupacao = ?, Renda = ?, DescontoEspecial = ?, PorcDescontoEspecial = ?, RecebeInfoMarketing = ?, CadastroAtivo = ? where IdPessoa = ?";

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlAtualizar;
            if (transacao != null)
                comando.Transaction = transacao as OleDbTransaction;

            OleDbParameter pNivel = new OleDbParameter("NivelPessoa", OleDbType.VarChar);
            string nivelPessoa = entidade.NivelPessoa;
            if (string.IsNullOrEmpty(nivelPessoa))
                pNivel.Value = "C";
            else
                pNivel.Value = nivelPessoa;
            comando.Parameters.Add(pNivel);

            OleDbParameter pUsuarioSistema = new OleDbParameter("UsuarioSistema", OleDbType.VarChar);
            pUsuarioSistema.Value = entidade.UsuarioSistema;
            comando.Parameters.Add(pUsuarioSistema);

            OleDbParameter pSenhaSistema = new OleDbParameter("SenhaSistema", OleDbType.VarChar);
            pSenhaSistema.Value = entidade.SenhaSistema;
            comando.Parameters.Add(pSenhaSistema);

            OleDbParameter pNomeCompleto = new OleDbParameter("NomeCompleto", OleDbType.VarChar);
            pNomeCompleto.Value = entidade.NomeCompleto;
            comando.Parameters.Add(pNomeCompleto);

            OleDbParameter pSexo = new OleDbParameter("Sexo", OleDbType.VarChar);
            pSexo.Value = entidade.Sexo;
            comando.Parameters.Add(pSexo);

            OleDbParameter pCPF = new OleDbParameter("CPF", OleDbType.VarChar);
            pCPF.Value = entidade.CPF;
            comando.Parameters.Add(pCPF);

            OleDbParameter pNascimento = new OleDbParameter("DataNascimento", OleDbType.Date);
            pNascimento.Value = entidade.DataNascimento;
            comando.Parameters.Add(pNascimento);

            OleDbParameter pEmail = new OleDbParameter("Email", OleDbType.VarChar);
            pEmail.Value = entidade.Email;
            comando.Parameters.Add(pEmail);

            OleDbParameter pIdEndereco = new OleDbParameter("IdEndereco", OleDbType.VarChar);
            pIdEndereco.Value = entidade.IdEndereco;
            comando.Parameters.Add(pIdEndereco);

            OleDbParameter pOcupacao = new OleDbParameter("Ocupacao", OleDbType.VarChar);
            string ocupacao = entidade.Ocupacao;
            if (string.IsNullOrEmpty(ocupacao))
                pOcupacao.Value = DBNull.Value;
            else
                pOcupacao.Value = ocupacao;
            comando.Parameters.Add(pOcupacao);

            OleDbParameter pRenda = new OleDbParameter("Renda", OleDbType.Numeric);
            Decimal? renda = entidade.Renda;
            if (renda == null || renda == 0)
                pRenda.Value = DBNull.Value;
            else
                pRenda.Value = renda;
            comando.Parameters.Add(pRenda);

            OleDbParameter pDescontoEspecial = new OleDbParameter("DescontoEspecial", OleDbType.VarChar);
            if (string.IsNullOrEmpty(entidade.DescontoEspecial))
                pDescontoEspecial.Value = "N";
            else
                pDescontoEspecial.Value = entidade.DescontoEspecial;
            comando.Parameters.Add(pDescontoEspecial);

            OleDbParameter pPorcDescontoEspecial = new OleDbParameter("PorcDescontoEspecial", OleDbType.Numeric);
            Decimal? porcDescontoEspecial = entidade.PorcDescontoEspecial;
            if (porcDescontoEspecial == null || porcDescontoEspecial == Decimal.Zero)
                pPorcDescontoEspecial.Value = 0.0;
            else
                pPorcDescontoEspecial.Value = porcDescontoEspecial;
            comando.Parameters.Add(pPorcDescontoEspecial);


            OleDbParameter pRecebeInfoMarketing = new OleDbParameter("RecebeInfoMarketing", OleDbType.VarChar);
            string recebeMarketing = entidade.RecebeInfoMarketing;
            if (string.IsNullOrEmpty(recebeMarketing))
                pRecebeInfoMarketing.Value = "S";
            else
                pRecebeInfoMarketing.Value = recebeMarketing;
            comando.Parameters.Add(pRecebeInfoMarketing);

            OleDbParameter pCadastroAtivo = new OleDbParameter("CadastroAtivo", OleDbType.VarChar);
            string cadastroAtivo = entidade.CadastroAtivo;
            if (string.IsNullOrEmpty(cadastroAtivo))
                pCadastroAtivo.Value = "N";
            else
                pCadastroAtivo.Value = cadastroAtivo;
            comando.Parameters.Add(pCadastroAtivo);

            OleDbParameter pIdPessoa = new OleDbParameter("IdPessoa", OleDbType.Integer);
            pIdPessoa.Value = entidade.IdPessoa;
            comando.Parameters.Add(pIdPessoa);


            // Update
            comando.ExecuteNonQuery();
            comando.Dispose();
        }

        public void RemoverPorId(int id, DbTransaction transacao)
        {
            string sqlDeletar = "delete PESSOA where IdPessoa = ?";

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlDeletar;
            if (transacao != null)
                comando.Transaction = transacao as OleDbTransaction;

            OleDbParameter pId = new OleDbParameter("IdPessoa", OleDbType.VarChar);
            pId.Value = id;
            comando.Parameters.Add(pId);

            // Delete
            comando.ExecuteNonQuery();
            comando.Dispose();
        }

        public Pessoa BuscarPorId(int id)
        {
            Pessoa registro = null;
            string sqlBuscar = "select * from PESSOA where IdPessoa = ?";

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlBuscar;

            OleDbParameter pId = new OleDbParameter("IdPessoa", OleDbType.Integer);
            pId.Value = id;
            comando.Parameters.Add(pId);

            // Select
            OleDbDataReader dr = comando.ExecuteReader();
            if (dr.Read())
            {
                registro = ConverterDataReaderParaObj(dr);
            }
            dr.Close();
            comando.Dispose();

            if (registro != null)
                CarregarComposicao(registro);

            return registro;
        }

        private void CarregarComposicao(Pessoa pessoa)
        {
            int idEndereco = pessoa.IdEndereco;
            Endereco endereco = enderecoDAO.BuscarPorId(idEndereco);
            pessoa.Endereco = endereco;

            int idPessoa = pessoa.IdPessoa;
            List<Telefone> telefones = telefoneDAO.ListarPorIdPessoa(idPessoa);
            pessoa.Telefones = telefones;
        }

        private Pessoa ConverterDataReaderParaObj(OleDbDataReader dr)
        {
            Pessoa registro = new Pessoa();
            registro.IdPessoa = Int32.Parse(dr["IdPessoa"].ToString());
            registro.NivelPessoa = dr["NivelPessoa"].ToString();
            registro.UsuarioSistema = dr["UsuarioSistema"].ToString();
            registro.SenhaSistema = dr["SenhaSistema"].ToString();
            registro.NomeCompleto = dr["NomeCompleto"].ToString();
            registro.Sexo = dr["Sexo"].ToString();
            registro.CPF = dr["CPF"].ToString();
            registro.DataNascimento = DateTime.Parse(dr["DataNascimento"].ToString());
            registro.Email = dr["Email"].ToString();
            registro.IdEndereco = Int32.Parse(dr["IdEndereco"].ToString());
            registro.Ocupacao = dr["ocupacao"].ToString();
            string rendaBanco = dr["renda"].ToString();
            if (!string.IsNullOrEmpty(rendaBanco))
            {
                registro.Renda = Decimal.Parse(rendaBanco);
            }
            registro.DescontoEspecial = dr["DescontoEspecial"].ToString();
            string porcDescontoEspeBanco = dr["PorcDescontoEspecial"].ToString();
            if (!string.IsNullOrEmpty(porcDescontoEspeBanco))
            {
                registro.PorcDescontoEspecial = Decimal.Parse(porcDescontoEspeBanco);
            }
            registro.RecebeInfoMarketing = dr["RecebeInfoMarketing"].ToString();
            registro.CadastroAtivo = dr["CadastroAtivo"].ToString();

            return registro;
        }

        public List<Pessoa> Listar()
        {
            String sqlConsulta = "select * from PESSOA order by NomeCompleto";

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlConsulta;

            // Select
            OleDbDataReader dr = comando.ExecuteReader();

            List<Pessoa> registros = new List<Pessoa>();
            while (dr.Read())
            {
                Pessoa registro = ConverterDataReaderParaObj(dr);
                registros.Add(registro);
            }
            dr.Close();
            comando.Dispose();

            foreach (var registro in registros)
            {
                CarregarComposicao(registro);
            }

            return registros;
        }


        public int ProximoIdPessoa(DbTransaction transacao = null)
        {
            string sqlConsultar
                = "select seqPessoa.nextval from dual";

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlConsultar;
            if (transacao != null)
                comando.Transaction = transacao as OleDbTransaction;

            // Select
            OleDbDataReader dr = comando.ExecuteReader();

            if (dr.Read())
            {
                int id = Convert.ToInt32(dr["NEXTVAL"]);
                dr.Close();
                comando.Dispose();
                return id;
            }
            
            dr.Close();
            comando.Dispose();
            throw new Exception("Erro ao recuperar o próximo ID de pessoa.");
        }




        public void AtivarCadastro(int id)
        {
            string sqlDeletar = "update PESSOA set CadastroAtivo = 'S' where IdPessoa = ?";

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlDeletar;

            OleDbParameter pId = new OleDbParameter("IdPessoa", OleDbType.VarChar);
            pId.Value = id;
            comando.Parameters.Add(pId);

            // Delete
            comando.ExecuteNonQuery();
        }


        public void DesativarCadastro(int id)
        {
            string sqlDeletar = "update PESSOA set CadastroAtivo = 'N' where IdPessoa = ?";

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlDeletar;

            OleDbParameter pId = new OleDbParameter("IdPessoa", OleDbType.VarChar);
            pId.Value = id;
            comando.Parameters.Add(pId);

            // Delete
            comando.ExecuteNonQuery();
        }
    }
}